import React, { createRef, PureComponent } from 'react'
import {
  Select, DatePicker, message, Table,
} from 'antd'
import { connect, history } from '@umijs/max'
import moment from 'moment'
import _ from 'lodash'
import {
  InputSearch, Logger, ProTable, ProTableOperate, ProTableOptions,
} from '@/components'
import Tools from '@/utils/Tools'
import styles from './index.less'

const Bus = Tools.Bus
const { Option } = Select
const { OperateItem } = ProTableOperate
const { RangePicker } = DatePicker

const nodeTypeList = [
  { 1: '工作流' },
  { 12: '开始节点' },
  { 13: 'SQL' },
  // { 14: 'MapReduce' },
  // { 15: 'Impala' },
  { 16: 'Shell' },
  { 17: 'Python2' },
  { 18: 'Python3' },
  // { 19: 'Pyspark' },
  { 20: '离线同步' },
  { 21: '接口采集' },
  { 22: '数据质量' },
]

const nodeTypeFn = () => {
  const tempList = []
  nodeTypeList.forEach(item => {
    tempList.push({ text: Object.values(item)[0], value: Number(Object.keys(item)[0]) })
  })
  return tempList
}

const nodeTypeText = (nodeType) => {
  let resText = '-'
  nodeTypeList?.map(item => {
    if (`${nodeType}` === Object.keys(item)[0]) {
      resText = Object.values(item)[0]
    }
  })
  return resText
}

const statusEnum = [
  { text: '未运行', value: 1, icon: 'icon-weiyunhang', color: 'hu-gray' },
  { text: '运行中', value: 2, icon: 'icon-yunhangzhong_1', color: 'hu-blue' },
  { text: '成功', value: 3, icon: 'icon-chenggong', color: 'hu-green'},
  { text: '失败', value: 4, icon: 'icon-shibai1', color: 'hu-red' },
  { text: '停止', value: 5, icon: 'icon-weiyunhang', color: 'hu-gray' },
  { text: '部分失败', value: 6, icon: 'icon-shibai1', color: 'hu-red' },
  { text: '已归档', value: 9, icon: 'icon-guidang', color: 'hu-blue' },
]

@connect(({ operation }) => ({ ...operation }))
class History extends PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      filter_status: this.props?.filteredDefaultValue || [],
      // filter_execType: this.props?.filteredDefaultValue?.[0] ? [1] : [], // 从概览页的失败数、成功数跳转到任务运行记录页，调度类型筛选都为 周期执行
      filter_execType: [],
      filter_nodeType: this.props?.filteredDefaultValue?.[0] ? [1] : [],
      taskStatus: null,
      execType: null,
      query: {
        nodeName: this.props?.defaultNodeName || '',
        status: this.props?.filteredDefaultValue?.join(',') || '',
        // execType: this.props?.filteredDefaultValue?.[0] ? 1 : '', // 从概览页的失败数、成功数跳转到任务运行记录页，调度类型筛选都为 周期执行
        execType: '', 
        nodeType: this.props?.filteredDefaultValue?.[0] ? 1 : '',
      },
      forceUpdateKey: 0,
      expandedRowKeys: [],
      // subTablesData: {},
      // expandedTableLoading: {},
      loading: false,
      modalVisible: false,
      runType: null,
      timeChecked: false,
      userList: [],
      optTypeParams: null,
      loggerList: [],
      nodeName: this.props?.defaultNodeName || ''
    }
    this.tableRef = createRef()
    this.logger = createRef()
  }

  componentDidMount() {
    this.queryUserList()
  }

  getColumn = () => (
    [
      {
        title: '任务名称',
        key: 'nodeName',
        width: '11%',
        render: (record) => (
          <span className={styles.link} onClick={() => { this.queryGetParentType(record?.nodeId, record?.nodeName) }}>{record?.nodeName}</span>
        ),
      },
      {
        title: '任务状态',
        dataIndex: 'status',
        key: 'status',
        width: '9%',
        filters: statusEnum,
        filteredValue: this.state.filter_status,
        // defaultFilteredValue: this.props?.filteredDefaultValue || [],
        // onFilter: (value, record) => record.status === value,
        render: (status) => {
          const statusEnumObj = statusEnum.filter(item => item.value === status)?.[0] || {}
          return (
            _.isEmpty(statusEnumObj) ? '-' : <><i className={`iconfont ${statusEnumObj.icon} ${statusEnumObj.color}`} /> {statusEnumObj.text} </>
          )
        },
      },
      {
        title: '任务类型',
        dataIndex: 'nodeType',
        key: 'nodeType',
        width: '8%',
        filters: nodeTypeFn(),
        filteredValue: this.state.filter_nodeType,
        render: (nodeType) => (nodeTypeText(nodeType)),
      },
      {
        title: '调度类型',
        dataIndex: 'execType',
        key: 'execType',
        width: '8%',
        filters: [
          { text: '手工执行', value: 0 },
          { text: '周期执行', value: 1 },
        ],
        filteredValue: this.state.filter_execType,
        // onFilter: (value, record) => record.execType === value,
        render: (execType) => (
          <>
            {execType === 0 && '手工执行'}
            {execType === 1 && '周期执行'}
          </>
        ),
      },
      {
        title: '计划开始时间',
        dataIndex: 'planTime',
        key: 'planTime',
        width: '13%',
        sorter: true,
        sortDirections: ['descend', 'ascend'],
      },
      {
        title: '启动时间',
        dataIndex: 'startTime',
        key: 'startTime',
        width: '13%',
        sorter: true,
        sortDirections: ['descend', 'ascend'],
      },
      {
        title: '结束时间',
        dataIndex: 'endTime',
        key: 'endTime',
        width: '13%',
        sorter: true,
        sortDirections: ['descend', 'ascend'],
      },
      {
        title: '运行时长(S)',
        dataIndex: 'time',
        key: 'time',
        width: '9%',
        sorter: true,
        sortDirections: ['descend', 'ascend'],
      },
      {
        title: '责任人',
        dataIndex: 'userName',
        key: 'userName',
        width: '7%',
      },
      {
        title: '操作',
        key: 'ignored',
        width: '9%',
        render: (record) => {
          const { id, status, ignored } = record
          return (
            <ProTableOptions size={4}>
                <span onClick={() => {
                  this.setState({
                    loggerList: [],
                  })
                  this.viewLog(id, this.state.offsets, false)
                  Bus.emit('iconUpFn2')
                }}
                >
                  查看日志
                </span>
              {
                (status !== 2 || null) && (
                  <span onClick={() => {
                    this.reRun(id)
                  }}>重跑</span>
                )
              }
              {
                (status === 2 || null) && (
                  <span onClick={() => {
                    this.setState({
                      loggerList: [],
                    })
                    this.queryStop([id], null)
                  }}
                  >
                      终止运行
                    </span>
                )
              }
              {
                (ignored !== 1 && status !== 2) && (
                  <span onClick={() => {
                    this.setState({
                      loggerList: [],
                    })
                    this.queryIgnore([id])
                  }}
                  >
                    归档
                  </span>
                )
              }
              {
                (ignored === 1) && (
                  <span>
                    已归档
                  </span>
                )
              }
            </ProTableOptions>
          )
        },
      },
    ]
  )

  queryUserList = () => {
    this.props.dispatch({
      type: 'operation/queryUserList',
      cb: (res) => {
        this.setState({
          userList: res || []
        })
      }
    })
  }

  fetchData = (isReset = true) => {
    const { userId, nodeName, endTime, startTime, query } = this.state
    isReset && this.tableRef?.current?.resetPageNum()
    const tempQuery = {}
    tempQuery.nodeName = nodeName || ''
    tempQuery.startTime = startTime || ''
    tempQuery.endTime = endTime || ''
    tempQuery.userId = userId || ''
    this.setState({
      query: {
        ...query,
        ...tempQuery,
      },
    })
  }

  // 归档任务
  queryIgnore = (idsArr) => {
    let idsStr = ''
    idsArr.map((item) => {
      if (idsStr !== '') idsStr += ','
      idsStr += item
      return null
    })
    this.setState({
      loading: true,
    })
    this.props.dispatch({
      type: 'operation/queryIgnore',
      params: {
        ids: idsStr,
      },
      cb: (res) => {
        const { status, msg } = res || {}

        // 后端需要2s的延时执行
        setTimeout(() => {
          this.setState({
            optTypeParams: null,
            loading: false,
          })
          if (status === 200) {
            message.success('操作成功')
            this.forceUpdateFn()
          } else {
            message.error(msg || '系统异常，请稍后重试~')
          }
        }, 2000)
      },
    })
  }

  // 批量归档任务
  batchIgnore = () => {
    const selectedRowKeys = this.tableRef?.current?.state?.selectedRowKeys
    if (selectedRowKeys.length < 1) {
      message.warning('请至少选择一条数据')
      return null
    }
    this.queryIgnore(selectedRowKeys)
  }

  // 批量停止任务
  queryStop = (idArr, optTypeParams) => {
    const selectedRowKeys = idArr?.length ? idArr : this.tableRef?.current?.state?.selectedRowKeys
    if (selectedRowKeys.length < 1) {
      message.warning('请至少选择一条数据')
      return null
    }
    let idsStr = ''
    selectedRowKeys.map((item) => {
      if (idsStr !== '') idsStr += ','
      idsStr += item
      return null
    })

    this.setState({
      optTypeParams,
      loading: true
    })
    this.props.dispatch({
      type: 'operation/queryStop',
      params: {
        logIds: idsStr,
      },
      cb: (res) => {
        const { status, msg } = res || {}

        // 后端需要2s的延时执行
        setTimeout(() => {
          this.setState({
            optTypeParams: null,
            loading: false,
          })
          if (status === 200) {
            message.success('操作成功')
            this.forceUpdateFn()
          } else {
            message.error(msg || '系统异常，请稍后重试~')
          }
        }, 2000)
      },
    })
  };

  forceUpdateFn = () => {
    this.setState((prevSta) => ({
      forceUpdateKey: prevSta.forceUpdateKey + 1,
    }))
  }

  // 重跑
  reRun = (id, pid) => {
    this.setState({ loading: true })
    this.props.dispatch({
      type: 'operation/queryRestartHistory',
      params: {
        id,
      },
      cb: (res) => {
        const { status, msg } = res || {}
        this.setState({
          loading: false,
        })
        if (status === 200) {
          message.success('操作成功')
          if (pid !== undefined) {
            this.querySubTask(pid)
          } else {
            this.fetchData(false)
          }
        } else {
          message.error(msg || '系统异常，请稍后重试~')
        }
      },
    })
  }

  // 查看日志
  viewLog = (jobId, offsets, bool) => {
    clearInterval(this.time)
    this.setState({
      loading: true,
    })
    this.props.dispatch({
      type: 'operation/queryLog',
      params: {
        jobId,
        offset: offsets || 0, // 参考老版本，传了固定值
      },
      cb: (res) => {
        const { status, msg, data } = res || {}
        this.setState({
          loading: false,
        })
        const domWrapper = document.querySelector('#layout_container_content')
        const currentScroll = domWrapper.scrollTop // 已经被卷掉的高度
        const scrollHeight = domWrapper.scrollHeight // 内容总高度
        domWrapper.scrollTo(0, (scrollHeight - currentScroll))

        if (status === 200) {
          this.setState((prevState) => ({
            loggerList: prevState.loggerList.concat(data?.logContent),
          }))
          this.time = setInterval(() => {
            if (data?.logEnd && bool) {
              clearInterval(this.time)
            } else if (data?.logEnd) {
              clearInterval(this.time)
            } else {
              this.viewLog(jobId, data?.offset, bool)
            }
          }, 4000)
        } else {
          message.error(msg || '系统异常，请稍后重试~')
        }
      },
    })
  }

  expandedRowRender = (record) => {
    const { id } = record
    const { subTablesData, expandedTableLoading } = this.state
    const copyColumns = this.getColumn() || []
    copyColumns.splice(0, 1)
    copyColumns.splice(copyColumns.length - 1, 1)
    const columns = [
      {
        title: '任务名称',
        dataIndex: 'nodeName',
        key: 'nodeName',
        width: '11%',
        render: (nodeName, subRecord) => (
          <span>{nodeName === "开始节点" ? <span>{nodeName}</span> : <span className={styles.link} onClick={() => { this.queryGetParentType(subRecord?.nodeId, nodeName) }}>{nodeName}</span>}</span>
        ),
      },
      ...copyColumns,
      {
        title: '操作',
        width: '9%',
        render: (subRecord) => {
          const { id, pid } = subRecord || {}
          return (
            <ProTableOptions>
              <span onClick={() => {
                this.setState({
                  loggerList: [],
                })
                this.viewLog(id, this.state.offsets, false)
                Bus.emit('iconUpFn2')
              }}
              >
                查看日志
              </span>
              <span
                onClick={() => {
                  // this.setState({
                  //   expandedRowKeys: [],
                  // })
                  this.reRun(id, pid)
                }}
              >
                重跑
              </span>
            </ProTableOptions>
          )
        },
      },
    ]

    return (
      <Table
        className={styles.sub_table}
        loading={!!expandedTableLoading?.[id]}
        rowKey="id"
        columns={columns}
        dataSource={subTablesData?.[id] || []}
        pagination={false}
        rowSelection={{
          type: 'checkbox',
          getCheckboxProps: () => ({
            disabled: true,
          }),
        }}
      />
    )
  }

  // 点击展开按钮发请求操作
  handleExpand = (expanded, record) => {
    const { id } = record
    if (expanded) {
      this.setState((prevState) => ({
        expandedRowKeys: [...prevState.expandedRowKeys, id],
        expandedTableLoading: {
          ...prevState.expandedTableLoading,
          [id]: true,
        },
      }))
      this.querySubTask(id)
    } else {
      const { expandedRowKeys } = this.state
      const filterArr = expandedRowKeys.filter(item => item !== id)
      this.setState({
        expandedRowKeys: [...filterArr],
      })
    }
  }

  // 获取子任务
  querySubTask = (id) => {
    this.props.dispatch({
      type: 'operation/queryJobChildren',
      params: { jobId: id },
      cb: (data = []) => {
        let spliceArr = []
        if (data?.length > 0) {
          data?.some((item, index) => {
            if (item.name === '开始节点') {
              if (index !== 0) {
                spliceArr = data?.splice(index, 1)
              }
            }
          })
        }

        const formatArr = [...spliceArr, ...data]

        this.setState((prevState) => ({
          subTablesData: {
            ...prevState.subTablesData,
            [id]: formatArr,
          },
          expandedTableLoading: {
            ...prevState.expandedTableLoading,
            [id]: false,
          },
        }))
      },
    })
  }

  queryGetParentType = (nodeId, nodeName) => {
    this.props.dispatch({
      type: 'operation/queryGetParentType',
      params: {
        nodeId,
      },
      cb: (res) => {
        const { msg, status, data } = res
        if (status === 200) {
          if (data === 1) {
            // 作业开发
            history.push(`/data-development/offline/script-development?nodeId=${nodeId}&nodeName=${nodeName}`)
          } else {
            history.push(`/data-development/offline/workflow-development?nodeId=${nodeId}&nodeName=${nodeName}`)
          }
        } else {
          message.error(msg || '服务端错误')
        }
      },
    })
  }

  handleTableChange = (pagination, filters, sorter) => {
    const queryFilter = {}
    for (const f in filters) {
      if (filters[f]) {
        queryFilter[f] = filters[f].join(',')
      }
      this.setState({ [`filter_${f}`]: filters[f] })
    }

    if (sorter?.order) {
      queryFilter.order = sorter?.order === 'descend' ? 'desc' : 'asc'
      queryFilter.orderField = sorter?.field
    }

    const { userId = '', nodeName = '', endTime = '', startTime = '' } = this.state
    this.tableRef?.current?.resetPageNum()

    const tempQuery = {
      nodeName, startTime, endTime, userId
    }

    this.setState({
      query: {
        ...tempQuery,
        ...queryFilter,
      },
    })
  }

  render() {
    const {
      loading, query, expandedRowKeys, nodeName, userList, forceUpdateKey, optTypeParams, loggerList,
    } = this.state
    const rowSelection = {
      type: 'checkbox',
    }

    return (
      <div className={`${styles.history} ${styles.page_content_with_breadcrumb}`}>
        <div className={styles.page_content_column}>
          <div className={`${styles.page_content_right} ${styles.page_content_right_flex}`}>
            <ProTableOperate style={{ marginBottom: 12 }}>
              <OperateItem>
                <span>责任人</span>
                <Select
                  allowClear
                  onChange={(value) => {
                    this.setState({
                      userId: value || '',
                    }, () => {
                      this.logger.current.iconDownFn()
                      this.fetchData()
                    })
                  }}
                >
                  {
                    userList?.map(item => (
                      <Option key={item.id} value={item.id}>{item.username}</Option>
                    ))
                  }
                </Select>
              </OperateItem>
              <OperateItem large_label>
                <span style={{ width: 100 }}>计划开始时间</span>
                <RangePicker
                  showTime
                  ranges={{
                    '今天': [moment(), moment()],
                    '最近7天': [moment().add(-7, 'd'), moment()],
                    '最近30天': [moment().add(-30, 'd'), moment()],
                  }}
                  onChange={(date, dateStr) => {
                    this.setState({
                      startTime: dateStr[0],
                      endTime: dateStr[1],
                    }, () => {
                      this.logger.current.iconDownFn()
                      this.fetchData()
                    })
                  }}
                />
              </OperateItem>
              <OperateItem align="left">
                <InputSearch
                  value={nodeName}
                  placeholder="请输入任务名称进行搜索"
                  onChange={(e) => {
                    this.setState({
                      nodeName: e.target.value,
                    })
                  }}
                  onSearch={() => {
                    this.logger.current.iconDownFn()
                    this.fetchData()
                  }}
                />
              </OperateItem>
            </ProTableOperate>

            <ProTable
              ref={this.tableRef}
              loading={loading}
              key={forceUpdateKey}
              url="/api/v1/offlineDev/operation/v2/jobList"
              query={query}
              rowKey="id"
              columns={this.getColumn()}
              expandedRowKeys={expandedRowKeys}
              expandable={{
                expandedRowRender: this.expandedRowRender,
                onExpand: this.handleExpand,
                rowExpandable: record => record.haveChildren,
                indentSize: 0,
              }}
              resetExpandedRowKeys={this.resetExpandedRowKeys}
              rowSelection={rowSelection}
              onChange={this.handleTableChange}
              bulkOperation={[
                {
                  title: '批量杀任务',
                  loading: optTypeParams === 0 ? loading : false,
                  onClick: (params) => { this.queryStop(params, 0) },
                },
                {
                  title: '批量归档任务',
                  loading: optTypeParams === 0 ? loading : false,
                  onClick: (params) => { this.batchIgnore(params, 0) },
                },
              ]}
            />
          </div>
          <Logger
            list={loggerList || []}
            ref={this.logger}
          />
        </div>
      </div>
    )
  }
}

export default History
